package com.liujit.standard.basis.core.util;

import cn.hutool.core.util.StrUtil;
import com.liujit.standard.basis.core.constants.HeaderConstants;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description: JWT工具类
 * @author: liujun
 * @create: 2021/3/24 4:59 下午
 **/
@Slf4j
public class JwtUtils {

    private static final String JWT_SECRET = "sHyPanQN8wAt3sKBix9Fla7iGvwWs4hfE4YhluMYvbtBdX6sOiEeGU4lHhVgdrsO";

    public static Map getJWT() {
        HttpServletRequest request = ReqUtil.getRequest();
        String jwtStr = request.getHeader(HeaderConstants.ADMIN_TOKEN);
        if (StrUtil.isEmpty(jwtStr)) {
            return null;
        }
        Claims c = getClaims(jwtStr);
        Map result = new HashMap();
        result.put("token", c.get("token"));
        result.put("uInfo", c.get("uInfo"));
        return result;
    }

    /**
     * 创建 JWT
     *
     * @param claims
     * @return
     * @Description jwt荷载
     * iss: jwt签发者
     * sub: jwt所面向的用户
     * aud: 接收jwt的一方
     * exp: jwt的过期时间，这个过期时间必须要大于签发时间
     * nbf: 定义在什么时间之前，该jwt都是不可用的.
     * iat: jwt的签发时间
     * jti: jwt的唯一身份标识，主要用来作为一次性token,从而回避重放攻击。
     */
    public static String generateJwt(Map<String, Object> claims, long Expiration) {

        //签发时间
        long nowMillis = System.currentTimeMillis();
        //超时时间
        long expMillis = nowMillis + Expiration;

        String compactJws = Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date(nowMillis))
                .setExpiration(new Date(expMillis))
                .signWith(SignatureAlgorithm.HS512, JWT_SECRET)
                .compact();

        return compactJws;
    }

    /**
     * 校验jwt是否合法
     *
     * @param jwt
     * @return
     */
    public static boolean checkJWT(String jwt) {
        try {
            getClaims(jwt);
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
    }

    /**
     * 获取claims
     *
     * @param jwt
     * @return
     */
    public static Claims getClaims(String jwt) {
        Claims claims;
        claims = Jwts.parser()
                .setSigningKey(JWT_SECRET)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }

}
